home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / glibc108.zip / glibc108 / sysdeps / generic / wordcopy.c < prev   
C/C++ Source or Header  |  1992-04-01  |  10KB  |  406 lines

  1. /* _memcopy.c -- subroutines for memory copy functions.
  2.    Copyright (C) 1991 Free Software Foundation, Inc.
  3.    Contributed by Torbjorn Granlund (tege@sics.se).
  4.  
  5. The GNU C Library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Library General Public License as
  7. published by the Free Software Foundation; either version 2 of the
  8. License, or (at your option) any later version.
  9.  
  10. The GNU C Library is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13. Library General Public License for more details.
  14.  
  15. You should have received a copy of the GNU Library General Public
  16. License along with the GNU C Library; see the file COPYING.LIB.  If
  17. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  18. Cambridge, MA 02139, USA.  */
  19.  
  20. /* BE VERY CAREFUL IF YOU CHANGE THIS CODE...!  */
  21.  
  22. #include <ansidecl.h>
  23. #include <stddef.h>
  24. #include <memcopy.h>
  25.  
  26. /* _wordcopy_fwd_aligned -- Copy block beginning at SRCP to
  27.    block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
  28.    Both SRCP and DSTP should be aligned for memory operations on `op_t's.  */
  29.  
  30. void
  31. DEFUN(_wordcopy_fwd_aligned, (dstp, srcp, len),
  32.       long int dstp AND long int srcp AND size_t len)
  33. {
  34.   op_t a0, a1;
  35.  
  36.   switch (len % 8)
  37.     {
  38.     case 2:
  39.       a0 = ((op_t *) srcp)[0];
  40.       srcp -= 6 * OPSIZ;
  41.       dstp -= 7 * OPSIZ;
  42.       len += 6;
  43.       goto do1;
  44.     case 3:
  45.       a1 = ((op_t *) srcp)[0];
  46.       srcp -= 5 * OPSIZ;
  47.       dstp -= 6 * OPSIZ;
  48.       len += 5;
  49.       goto do2;
  50.     case 4:
  51.       a0 = ((op_t *) srcp)[0];
  52.       srcp -= 4 * OPSIZ;
  53.       dstp -= 5 * OPSIZ;
  54.       len += 4;
  55.       goto do3;
  56.     case 5:
  57.       a1 = ((op_t *) srcp)[0];
  58.       srcp -= 3 * OPSIZ;
  59.       dstp -= 4 * OPSIZ;
  60.       len += 3;
  61.       goto do4;
  62.     case 6:
  63.       a0 = ((op_t *) srcp)[0];
  64.       srcp -= 2 * OPSIZ;
  65.       dstp -= 3 * OPSIZ;
  66.       len += 2;
  67.       goto do5;
  68.     case 7:
  69.       a1 = ((op_t *) srcp)[0];
  70.       srcp -= 1 * OPSIZ;
  71.       dstp -= 2 * OPSIZ;
  72.       len += 1;
  73.       goto do6;
  74.       
  75.     case 0:
  76.       if (OP_T_THRES <= 3 * OPSIZ && len == 0)
  77.     return;
  78.       a0 = ((op_t *) srcp)[0];
  79.       srcp -= 0 * OPSIZ;
  80.       dstp -= 1 * OPSIZ;
  81.       goto do7;
  82.     case 1:
  83.       a1 = ((op_t *) srcp)[0];
  84.       srcp -=-1 * OPSIZ;
  85.       dstp -= 0 * OPSIZ;
  86.       len -= 1;
  87.       if (OP_T_THRES <= 3 * OPSIZ && len == 0)
  88.     goto do0;
  89.       goto do8;            /* No-op.  */
  90.     }
  91.  
  92.   do
  93.     {
  94.     do8:
  95.       a0 = ((op_t *) srcp)[0];
  96.       ((op_t *) dstp)[0] = a1;
  97.     do7:
  98.       a1 = ((op_t *) srcp)[1];
  99.       ((op_t *) dstp)[1] = a0;
  100.     do6:
  101.       a0 = ((op_t *) srcp)[2];
  102.       ((op_t *) dstp)[2] = a1;
  103.     do5:
  104.       a1 = ((op_t *) srcp)[3];
  105.       ((op_t *) dstp)[3] = a0;
  106.     do4:
  107.       a0 = ((op_t *) srcp)[4];
  108.       ((op_t *) dstp)[4] = a1;
  109.     do3:
  110.       a1 = ((op_t *) srcp)[5];
  111.       ((op_t *) dstp)[5] = a0;
  112.     do2:
  113.       a0 = ((op_t *) srcp)[6];
  114.       ((op_t *) dstp)[6] = a1;
  115.     do1:
  116.       a1 = ((op_t *) srcp)[7];
  117.       ((op_t *) dstp)[7] = a0;
  118.  
  119.       srcp += 8 * OPSIZ;
  120.       dstp += 8 * OPSIZ;
  121.       len -= 8;
  122.     }
  123.   while (len != 0);
  124.  
  125.   /* This is the right position for do0.  Please don't move
  126.      it into the loop.  */
  127.  do0:
  128.   ((op_t *) dstp)[0] = a1;
  129. }
  130.  
  131. /* _wordcopy_fwd_dest_aligned -- Copy block beginning at SRCP to
  132.    block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
  133.    DSTP should be aligned for memory operations on `op_t's, but SRCP must
  134.    *not* be aligned.  */
  135.  
  136. void
  137. DEFUN(_wordcopy_fwd_dest_aligned, (dstp, srcp, len),
  138.       long int dstp AND long int srcp AND size_t len)
  139. {
  140.   op_t a0, a1, a2, a3;
  141.   int sh_1, sh_2;
  142.  
  143.   /* Calculate how to shift a word read at the memory operation
  144.      aligned srcp to make it aligned for copy.  */
  145.  
  146.   sh_1 = 8 * (srcp % OPSIZ);
  147.   sh_2 = 8 * OPSIZ - sh_1;
  148.  
  149.   /* Make SRCP aligned by rounding it down to the beginning of the `op_t'
  150.      it points in the middle of.  */
  151.   srcp &= -OPSIZ;
  152.  
  153.   switch (len % 4)
  154.     {
  155.     case 2:
  156.       a1 = ((op_t *) srcp)[0];
  157.       a2 = ((op_t *) srcp)[1];
  158.       srcp -= 1 * OPSIZ;
  159.       dstp -= 3 * OPSIZ;
  160.       len += 2;
  161.       goto do1;
  162.     case 3:
  163.       a0 = ((op_t *) srcp)[0];
  164.       a1 = ((op_t *) srcp)[1];
  165.       srcp -= 0 * OPSIZ;
  166.       dstp -= 2 * OPSIZ;
  167.       len += 1;
  168.       goto do2;
  169.     case 0:
  170.       if (OP_T_THRES <= 3 * OPSIZ && len == 0)
  171.     return;
  172.       a3 = ((op_t *) srcp)[0];
  173.       a0 = ((op_t *) srcp)[1];
  174.       srcp -=-1 * OPSIZ;
  175.       dstp -= 1 * OPSIZ;
  176.       len += 0;
  177.       goto do3;
  178.     case 1:
  179.       a2 = ((op_t *) srcp)[0];
  180.       a3 = ((op_t *) srcp)[1];
  181.       srcp -=-2 * OPSIZ;
  182.       dstp -= 0 * OPSIZ;
  183.       len -= 1;
  184.       if (OP_T_THRES <= 3 * OPSIZ && len == 0)
  185.     goto do0;
  186.       goto do4;            /* No-op.  */
  187.     }
  188.  
  189.   do
  190.     {
  191.     do4:
  192.       a0 = ((op_t *) srcp)[0];
  193.       ((op_t *) dstp)[0] = MERGE (a2, sh_1, a3, sh_2);
  194.     do3:
  195.       a1 = ((op_t *) srcp)[1];
  196.       ((op_t *) dstp)[1] = MERGE (a3, sh_1, a0, sh_2);
  197.     do2:
  198.       a2 = ((op_t *) srcp)[2];
  199.       ((op_t *) dstp)[2] = MERGE (a0, sh_1, a1, sh_2);
  200.     do1:
  201.       a3 = ((op_t *) srcp)[3];
  202.       ((op_t *) dstp)[3] = MERGE (a1, sh_1, a2, sh_2);
  203.  
  204.       srcp += 4 * OPSIZ;
  205.       dstp += 4 * OPSIZ;
  206.       len -= 4;
  207.     }
  208.   while (len != 0);
  209.  
  210.   /* This is the right position for do0.  Please don't move
  211.      it into the loop.  */
  212.  do0:
  213.   ((op_t *) dstp)[0] = MERGE (a2, sh_1, a3, sh_2);
  214. }
  215.  
  216. /* _wordcopy_bwd_aligned -- Copy block finishing right before
  217.    SRCP to block finishing right before DSTP with LEN `op_t' words
  218.    (not LEN bytes!).  Both SRCP and DSTP should be aligned for memory
  219.    operations on `op_t's.  */
  220.  
  221. void
  222. DEFUN(_wordcopy_bwd_aligned, (dstp, srcp, len),
  223.       long int dstp AND long int srcp AND size_t len)
  224. {
  225.   op_t a0, a1;
  226.  
  227.   switch (len % 8)
  228.     {
  229.     case 2:
  230.       srcp -= 2 * OPSIZ;
  231.       dstp -= 1 * OPSIZ;
  232.       a0 = ((op_t *) srcp)[1];
  233.       len += 6;
  234.       goto do1;
  235.     case 3:
  236.       srcp -= 3 * OPSIZ;
  237.       dstp -= 2 * OPSIZ;
  238.       a1 = ((op_t *) srcp)[2];
  239.       len += 5;
  240.       goto do2;
  241.     case 4:
  242.       srcp -= 4 * OPSIZ;
  243.       dstp -= 3 * OPSIZ;
  244.       a0 = ((op_t *) srcp)[3];
  245.       len += 4;
  246.       goto do3;
  247.     case 5:
  248.       srcp -= 5 * OPSIZ;
  249.       dstp -= 4 * OPSIZ;
  250.       a1 = ((op_t *) srcp)[4];
  251.       len += 3;
  252.       goto do4;
  253.     case 6:
  254.       srcp -= 6 * OPSIZ;
  255.       dstp -= 5 * OPSIZ;
  256.       a0 = ((op_t *) srcp)[5];
  257.       len += 2;
  258.       goto do5;
  259.     case 7:
  260.       srcp -= 7 * OPSIZ;
  261.       dstp -= 6 * OPSIZ;
  262.       a1 = ((op_t *) srcp)[6];
  263.       len += 1;
  264.       goto do6;
  265.       
  266.     case 0:
  267.       if (OP_T_THRES <= 3 * OPSIZ && len == 0)
  268.     return;
  269.       srcp -= 8 * OPSIZ;
  270.       dstp -= 7 * OPSIZ;
  271.       a0 = ((op_t *) srcp)[7];
  272.       goto do7;
  273.     case 1:
  274.       srcp -= 9 * OPSIZ;
  275.       dstp -= 8 * OPSIZ;
  276.       a1 = ((op_t *) srcp)[8];
  277.       len -= 1;
  278.       if (OP_T_THRES <= 3 * OPSIZ && len == 0)
  279.     goto do0;
  280.       goto do8;            /* No-op.  */
  281.     }
  282.  
  283.   do
  284.     {
  285.     do8:
  286.       a0 = ((op_t *) srcp)[7];
  287.       ((op_t *) dstp)[7] = a1;
  288.     do7:
  289.       a1 = ((op_t *) srcp)[6];
  290.       ((op_t *) dstp)[6] = a0;
  291.     do6:
  292.       a0 = ((op_t *) srcp)[5];
  293.       ((op_t *) dstp)[5] = a1;
  294.     do5:
  295.       a1 = ((op_t *) srcp)[4];
  296.       ((op_t *) dstp)[4] = a0;
  297.     do4:
  298.       a0 = ((op_t *) srcp)[3];
  299.       ((op_t *) dstp)[3] = a1;
  300.     do3:
  301.       a1 = ((op_t *) srcp)[2];
  302.       ((op_t *) dstp)[2] = a0;
  303.     do2:
  304.       a0 = ((op_t *) srcp)[1];
  305.       ((op_t *) dstp)[1] = a1;
  306.     do1:
  307.       a1 = ((op_t *) srcp)[0];
  308.       ((op_t *) dstp)[0] = a0;
  309.  
  310.       srcp -= 8 * OPSIZ;
  311.       dstp -= 8 * OPSIZ;
  312.       len -= 8;
  313.     }
  314.   while (len != 0);
  315.  
  316.   /* This is the right position for do0.  Please don't move
  317.      it into the loop.  */
  318.  do0:
  319.   ((op_t *) dstp)[7] = a1;
  320. }
  321.  
  322. /* _wordcopy_bwd_dest_aligned -- Copy block finishing right
  323.    before SRCP to block finishing right before DSTP with LEN `op_t'
  324.    words (not LEN bytes!).  DSTP should be aligned for memory
  325.    operations on `op_t', but SRCP must *not* be aligned.  */
  326.  
  327. void
  328. DEFUN(_wordcopy_bwd_dest_aligned, (dstp, srcp, len),
  329.       long int dstp AND long int srcp AND size_t len)
  330. {
  331.   op_t a0, a1, a2, a3;
  332.   int sh_1, sh_2;
  333.  
  334.   /* Calculate how to shift a word read at the memory operation
  335.      aligned srcp to make it aligned for copy.  */
  336.  
  337.   sh_1 = 8 * (srcp % OPSIZ);
  338.   sh_2 = 8 * OPSIZ - sh_1;
  339.  
  340.   /* Make srcp aligned by rounding it down to the beginning of the op_t
  341.      it points in the middle of.  */
  342.   srcp &= -OPSIZ;
  343.   srcp += OPSIZ;
  344.  
  345.   switch (len % 4)
  346.     {
  347.     case 2:
  348.       srcp -= 3 * OPSIZ;
  349.       dstp -= 1 * OPSIZ;
  350.       a2 = ((op_t *) srcp)[2];
  351.       a1 = ((op_t *) srcp)[1];
  352.       len += 2;
  353.       goto do1;
  354.     case 3:
  355.       srcp -= 4 * OPSIZ;
  356.       dstp -= 2 * OPSIZ;
  357.       a3 = ((op_t *) srcp)[3];
  358.       a2 = ((op_t *) srcp)[2];
  359.       len += 1;
  360.       goto do2;
  361.     case 0:
  362.       if (OP_T_THRES <= 3 * OPSIZ && len == 0)
  363.     return;
  364.       srcp -= 5 * OPSIZ;
  365.       dstp -= 3 * OPSIZ;
  366.       a0 = ((op_t *) srcp)[4];
  367.       a3 = ((op_t *) srcp)[3];
  368.       goto do3;
  369.     case 1:
  370.       srcp -= 6 * OPSIZ;
  371.       dstp -= 4 * OPSIZ;
  372.       a1 = ((op_t *) srcp)[5];
  373.       a0 = ((op_t *) srcp)[4];
  374.       len -= 1;
  375.       if (OP_T_THRES <= 3 * OPSIZ && len == 0)
  376.     goto do0;
  377.       goto do4;            /* No-op.  */
  378.     }
  379.  
  380.   do
  381.     {
  382.     do4:
  383.       a3 = ((op_t *) srcp)[3];
  384.       ((op_t *) dstp)[3] = MERGE (a0, sh_1, a1, sh_2);
  385.     do3:
  386.       a2 = ((op_t *) srcp)[2];
  387.       ((op_t *) dstp)[2] = MERGE (a3, sh_1, a0, sh_2);
  388.     do2:
  389.       a1 = ((op_t *) srcp)[1];
  390.       ((op_t *) dstp)[1] = MERGE (a2, sh_1, a3, sh_2);
  391.     do1:
  392.       a0 = ((op_t *) srcp)[0];
  393.       ((op_t *) dstp)[0] = MERGE (a1, sh_1, a2, sh_2);
  394.  
  395.       srcp -= 4 * OPSIZ;
  396.       dstp -= 4 * OPSIZ;
  397.       len -= 4;
  398.     }
  399.   while (len != 0);
  400.  
  401.   /* This is the right position for do0.  Please don't move
  402.      it into the loop.  */
  403.  do0:
  404.   ((op_t *) dstp)[3] = MERGE (a0, sh_1, a1, sh_2);
  405. }
  406.